﻿// This file is part of Code4Public (http://code4public.codeplex.com)
// Copyright 2011 Sina Iravanian - <sina@sinairv.com>
//
// This source file(s) may be redistributed, altered and customized
// by any means PROVIDING the authors name and all copyright
// notices remain intact.
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
// ------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Diagnostics;
using YAXLib;

namespace Code4Public.Settings
{
    [YAXSerializeAs("root")]
    public class ThemesCollection : List<Theme>
    {
        public ThemesCollection()
        {
            
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ThemesCollection"/> class, loading the 
        /// contents from the given file.
        /// </summary>
        /// <param name="path">The path of the themes file.</param>
        public ThemesCollection(string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("path cannot be empty or null!", "path");

            if (!File.Exists(path))
                throw new FileNotFoundException("The specified file cannot be found!", path);

            var ser = new YAXSerializer(typeof(ThemesCollection), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            var col = (ThemesCollection)ser.DeserializeFromFile(path);
            Debug.Assert(col != null);
            AddRange(col);
            ParsingErrors = ser.ParsingErrors;
        }

        public void SaveToFile(string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("Path cannot be empty or null!", "path");

            var ser = new YAXSerializer(typeof(ThemesCollection), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            ser.SerializeToFile(this, path);
        }

        /// <summary>
        /// Gets an array of themes names
        /// </summary>
        public IEnumerable<string> ThemeNames
        {
            get
            {
                return from Theme th in this select th.Name;
            }
        }

        /// <summary>
        /// Gets a reference to the selected theme, <c>null</c> if there are
        /// no themes selected.
        /// To select a theme one must select it by name 
        /// through the <c>SelectedThemeName</c> property.
        /// </summary>
        public Theme SelectedTheme { get; private set; }

        /// <summary>
        /// Gets a value indicating whether any theme is selected.
        /// To select a theme one must use the <code>SelectedThemeName</code> property.
        /// </summary>
        public bool IsAnyThemeSelected
        {
            get 
            { 
                return SelectedTheme != null; 
            }
        }

        /// <summary>
        /// Gets or sets the name of the selected theme. returns null if no themes are selected.
        /// </summary>
        public string SelectedThemeName
        {
            get 
            {
                return IsAnyThemeSelected ? SelectedTheme.Name : null;
            }

            set
            {
                var foundTheme = this.FirstOrDefault(theme => theme.Name == value);
                SelectedTheme = foundTheme;
                if (foundTheme == null)
                    throw new ArgumentException("No theme with this name is found: " + value, "value");
            }
        }

        public void SelectNoThemes()
        {
            SelectedTheme = null;
        }

        public bool ThemeExists(string themeName)
        {
            return this.Any(theme => theme.Name == themeName);
        }

        /// <summary>
        /// Gets a reference to the collection of parsing errors.
        /// </summary>
        public YAXParsingErrors ParsingErrors { get; private set; }

        /// <summary>
        /// Gets if there were any errors during parsing the Themes file.
        /// </summary>
        public bool HasErrors
        {
            get
            {
                return ParsingErrors != null && ParsingErrors.Count > 0;
            }
        }
    }
}
